package com.csproj.basic.service;

import com.csproj.basic.BasicService;
import com.csproj.basic.domain.Path;
import com.csproj.basic.repository.PathRepository;
import com.csproj.basic.service.dto.PathDTO;
import com.csproj.basic.service.mapper.PathMapper;
import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.base.common.exception.BaseAppException;
import com.csproj.siiat.base.common.util.FileUtils;
import com.csproj.siiat.security.SecurityUtils;
import com.csproj.system.service.UserInfoService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.time.ZonedDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Service Implementation for managing Path.
 */
@Service
@Transactional
public class PathService extends BasicService<PathDTO> {

    private final Logger log = LoggerFactory.getLogger(PathService.class);

    private final PathRepository pathRepository;

    private final PathMapper pathMapper;

    private final UserInfoService userInfoService;

    public PathService(PathRepository pathRepository, PathMapper pathMapper, UserInfoService userInfoService) {
        this.pathRepository = pathRepository;
        this.pathMapper = pathMapper;
        this.userInfoService = userInfoService;
    }

    /**
     * 保存区域并且返回前端需要发的dto，包括扩展属性createName
     * @param pathDto
     * @return pathDto
     * TODO 主要负责从前端接收值
     * TODO DTO的扩展属性，在此方法复制
     */
    public PathDTO saveAndGetDTO(PathDTO pathDto) {
        //如果该路径为默认路径 设置其他全部路径为非默认
        if(pathDto.isDefaultFlag()){
            pathRepository.updateNotDefault(pathDto.getStartWarehouseId(), pathDto.getEndWarehouseId());
        }
        //保存路径
        Path path = pathMapper.toEntity(pathDto);
        path = save(path);
        pathDto = pathMapper.toDto(path);

        return pathDto;
    }

    /**
     * 保存区域
     * @param path
     * @return path
     * TODO 纯粹的保存方法，通用于所有保存业务调用
     * TODO 赋默认值，保存后，检查数据库，是否所有字段都有准确值
     */
    public Path save(Path path) {
        Path entity = pathRepository.findFirstByPathNoAndDeletedFlagIsFalse(path.getPathNo());

        if(StringUtils.isNotBlank(path.getId())){
            if(entity!=null && !entity.getId().equals(path.getId())) {
                throw new BaseAppException(false,"duplicate_name");
            }

        }else if(entity!=null){
            throw  new BaseAppException(false,"duplicate_name");
        }
        path.setCreationTime(ZonedDateTime.now());
        path.setCreatorUserId(SecurityUtils.getCurrentUserId());
        path.setDeletedFlag(false);
        return pathRepository.save(path);
    }

    /**
     * 修改区域并且返回前端需要发的dto，包括扩展属性
     * @param pathDTO
     * @return pathDTO
     * TODO 类似SAVE
     */
    public PathDTO updateAndGetDTO(PathDTO pathDTO) {
        Path path = pathRepository.findOne(pathDTO.getId());
        if(path == null){
            throw new BaseAppException(BaseDTO.CODE_PARAM,"id_errors");
        }
        //path.setAreaName(pathDTO.getAreaName());

        path = update(path);
        return pathMapper.toDto(path);
    }

    /**
     * 修改区域
     * @param path
     * @return path
     * TODO 类似SAVE
     */
    public Path update(Path path) {
        Path entity = pathRepository.findFirstByPathNoAndDeletedFlagIsFalse(path.getPathNo());

        if(StringUtils.isNotBlank(path.getId())){
            if(entity!=null && !entity.getId().equals(path.getId())) {
                throw new BaseAppException(false,"duplicate_name");
            }

        }else if(entity!=null){
            throw  new BaseAppException(false,"duplicate_name");
        }
        Path pathDB = findOne(path.getId());
        pathDB.setEndWarehouseId(path.getEndWarehouseId());
        pathDB.setStartWarehouseId(path.getStartWarehouseId());
        pathDB.setPathNo(path.getPathNo());
        pathDB = pathRepository.save(pathDB);
        return pathDB;
    }




    /**
     * TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     *
     * @return the list of entities
     */
    @Transactional(readOnly = true)
    public List<Path> findAll() {
        log.debug("Request to get all Containers");
        List<Path> list = pathRepository.findAllEnabled();
        return list;
    }

    /**
     *  获取所有区域信息
     *  @return
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，可写多个findAllAndGetDTO1、findAllAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public List<PathDTO> findAllAndGetDTO() {
        List<PathDTO> list = pathMapper.toDto(findAll());
        return list;
    }

    /**
     * 根据id，获取区域信息
     *  @param id the id of the entity
     *  @return the entity
     *
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public Path findOne(String id) {
        Path area = pathRepository.findOne(id);
        if(area == null){
            throw new BaseAppException(BaseDTO.CODE_PARAM,"id_errors");
        }
        return area;
    }


    /**
     *  获取所有路径信息（分页）
     *  @return the list of entities
     *
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public Page<Path> findPageList(Map<String, Object> map, Pageable pageable) {
        Page<Path> result = pathRepository.findPageList(map,pageable);
        return result;
    }

    /**
     *  根据站点获取所有路径信息（不分页）
     *  @return the list of entities
     *
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public List<Path> findListBySiteId(Map<String, Object> map) {
        List<Path> result = pathRepository.findListBySiteId(map);
        return result;
    }
    /**
     *  获取所有区域信息（分页）
     *  @return the list of entities
     *
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，findPageListAndGetDTO1、findPageListAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public BaseDTO findPageListAndGetDTO(Map<String,Object> map, Pageable pageable) {
        String siteId = userInfoService.getCurrentUserSiteId();
        if(StringUtils.isNotBlank(siteId)&&!siteId.equals("nositeID"))
            map.put("siteId", siteId);
        Page<Path> result = findPageList(map,pageable);
        List<Path> paths = result.getContent();
        List<PathDTO> pathDTOS = pathMapper.toDto(paths);

        extendSiteName(pathDTOS,"startSiteId","startSiteName");
        extendSiteName(pathDTOS,"endSiteId","endSiteName");
        extendCompanyName(pathDTOS,"startWarehouseId","startWarehouseName");
        extendCompanyName(pathDTOS,"endWarehouseId","endWarehouseName");
        extendDictionaryTypeName(pathDTOS,"type","typeName","path_type");
        return BaseDTO.createBaseDTO(result).setFieldList(pathDTOS);
    }


    /**
     * 根据id，获取区域信息
     *  @param id 主键id
     *  @return creator、questionTypeName
     *
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，findPageListAndGetDTO1、findPageListAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public PathDTO findOneAndGetDTO(String id) {
        Path path = findOne(id);
        PathDTO pathDTO = pathMapper.toDto(path);
        return pathDTO;
    }

    /**
     *  根据id，删除区域信息
     *  @param id the id of the entity
     */
    public void delete(String id) {
        pathRepository.delete(id);
    }

    /**
     * 根据机构ids，批量删除区域信息
     * @param ids
     */
    public void deleteIds(String[] ids){
        pathRepository.deleteIds(ids);
    }

    /**
     * 上传文件
     * @param file
     */
    public String uploadFile(HttpServletRequest request, MultipartFile file){
        String filePath = FileUtils.excelUpload(request,file, File.separator+"upload"+ File.separator+"warehouse");
        return filePath;
    }

    /**
     * 更新状态
     * @param pathDTO
     */
    public PathDTO updateEnableFlag(PathDTO pathDTO) {
        String id = pathDTO.getId();
        if(StringUtils.isBlank(id)){
            return pathDTO;
        }
        String reason = pathDTO.getReason();
        Boolean enableFlag = pathDTO.isEnableFlag();
        pathRepository.updateEnableFlag(id,reason,enableFlag);
        return pathDTO;
    }
}
